package org.jeecg.modules.wlhy.fanyun.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.CheckBankCardIUtil;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.paycenter.channel.bankdocking.utils.BankUtils;
import org.jeecg.modules.third.daikai.fanyun.dto.FyApiBaseResDTO;
import org.jeecg.modules.third.daikai.fanyun.dto.contract.CarrierContractDTO;
import org.jeecg.modules.third.daikai.fanyun.dto.contract.CuoheContractDTO;
import org.jeecg.modules.third.daikai.fanyun.dto.finance.FySettlement;
import org.jeecg.modules.third.daikai.fanyun.dto.finance.FySettlementDTO;
import org.jeecg.modules.third.daikai.fanyun.dto.gps.FyGpsDTO;
import org.jeecg.modules.third.daikai.fanyun.dto.gps.GpsDataDTO;
import org.jeecg.modules.third.daikai.fanyun.dto.order.*;
import org.jeecg.modules.third.daikai.fanyun.dto.payee.FyPayeeDTO;
import org.jeecg.modules.third.daikai.fanyun.service.FanyunApiService;
import org.jeecg.modules.third.openapi.WaybillRouteService;
import org.jeecg.modules.wlhy.bill.entity.HyShippingNoteBill;
import org.jeecg.modules.wlhy.bill.service.IHyShippingNoteBillService;
import org.jeecg.modules.wlhy.customer.entity.HyCustomer;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerService;
import org.jeecg.modules.wlhy.fanyun.entity.FyUpDataShippingNoteDTO;
import org.jeecg.modules.wlhy.fanyun.entity.HyFyShipping;
import org.jeecg.modules.wlhy.fanyun.mapper.HyFyShippingMapper;
import org.jeecg.modules.wlhy.fanyun.service.IHyFyDriverService;
import org.jeecg.modules.wlhy.fanyun.service.IHyFyShippingService;
import org.jeecg.modules.wlhy.fanyun.service.IHyFyVehicleService;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriver;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriverAccountBook;
import org.jeecg.modules.wlhy.hydriver.service.IHyDriverAccountBookService;
import org.jeecg.modules.wlhy.hydriver.service.IHyDriverService;
import org.jeecg.modules.wlhy.hydriverbank.entity.HyDriverBank;
import org.jeecg.modules.wlhy.hydriverbank.service.IHyDriverBankService;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicle;
import org.jeecg.modules.wlhy.hyvehicle.service.IHyVehicleService;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;
import org.jeecg.modules.wlhy.shipping.entity.PointDataListVO;
import org.jeecg.modules.wlhy.shipping.entity.WaybillRouteVO;
import org.jeecg.modules.wlhy.shipping.service.IHyShippingNoteService;
import org.jeecg.modules.wlhy.utils.BankTypeUtil;
import org.jeecg.modules.wlhy.utils.HyCfgUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Description: hy_fy_shipping
 * @Author: duanlikao
 * @Date:   2023-02-08
 * @Version: V1.0
 */
@Service
public class HyFyShippingServiceImpl extends ServiceImpl<HyFyShippingMapper, HyFyShipping> implements IHyFyShippingService {

    private static final Logger LOGGER = LoggerFactory.getLogger(HyFyShippingServiceImpl.class);

    @Resource
    private FanyunApiService fanyunApiService ;

    @Resource
    private IHyShippingNoteService hyShippingNoteService;

    @Resource
    private IHyShippingNoteBillService hyShippingNoteBillService;

    @Resource
    private IHyFyDriverService hyFyDriverService;

    @Resource
    private IHyFyVehicleService hyFyVehicleService ;

    @Resource
    private IHyFyShippingService hyFyShippingService;

    @Autowired
    private IHyDriverService driverService;

    @Autowired
    private IHyVehicleService vehicleService;

    @Autowired
    private IHyDriverBankService hyDriverBankService;

    @Autowired
    private WaybillRouteService waybillRouteService;

    @Autowired
    private IHyDriverAccountBookService hyDriverAccountBookService;

    @Autowired
    private IHyCustomerService customerService;

    @Override
    public IPage<FyUpDataShippingNoteDTO> getFanyunUpDataPageList(Page<FyUpDataShippingNoteDTO> page,
                                                                  QueryWrapper<FyUpDataShippingNoteDTO> queryWrapper) {
        IPage<FyUpDataShippingNoteDTO> pageList = this.baseMapper.getFanyungUpDataPageList(page, queryWrapper);
        return pageList;
    }


    @Override
    public Result uploadFanyun(FyUpDataShippingNoteDTO fyUpDataShippingNoteDTO){

        HyShippingNote shippingNote = hyShippingNoteService.getById(fyUpDataShippingNoteDTO.getId());
        if (shippingNote == null) {
            throw new JeecgBootException("该运单上报信息不能为空");
        }

        if(StringUtils.isBlank(shippingNote.getContractNum() ) || StringUtils.isBlank(shippingNote.getShippingContract())){
            throw new JeecgBootException("该运单合同信息不能为空");
        }

        HyCustomer hyCustomer = customerService.getById(fyUpDataShippingNoteDTO.getCustomerId());
        if (hyCustomer == null) {
            throw new JeecgBootException("该运单上报货主信息不能为空");
        }

        LambdaQueryWrapper<HyShippingNoteBill> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HyShippingNoteBill::getShippingId, shippingNote.getId());
        List<HyShippingNoteBill> hyShippingNoteBills = hyShippingNoteBillService.list(queryWrapper);
        if (hyShippingNoteBills.isEmpty()) {
            throw new JeecgBootException("该运单流水单信息不存在！");
        }
        HyDriver hyDriver = driverService.getById(shippingNote.getDriverId());
        if (hyDriver == null) {
            throw new JeecgBootException("该运单司机信息不能为空");
        }
        HyVehicle hyVehicle = vehicleService.getById(shippingNote.getVehicleId());
        if (hyVehicle == null) {
            throw new JeecgBootException("该运单车辆信息不能为空");
        }

//        HyDriverAccountBook hyDriverAccountBook = hyDriverAccountBookService.getAccountBookByDriverId(hyDriver.getId());
//        if (hyDriverAccountBook == null) {
//            throw new JeecgBootException("未获取到司机钱包账户信息!");
//        }

        HyDriverBank hyDriverBank = this.hyDriverBankService.getDriverSelfBank(hyDriver.getId());
        if (hyDriverBank == null) {
            throw new JeecgBootException("未找到司机银行卡信息");
        }

        //String domianURL = fyUpDataShippingNoteDTO.getDomain();
        String domainURL = HyCfgUtil.getCfgItem2("fanyun_daikai","domain");
        if (StrUtil.isEmpty(domainURL)) {
            throw new JeecgBootException("域名配置不存在");
        }

//        if(!"1".equals( fyUpDataShippingNoteDTO.getDriverUploadStatus() )){
//            hyFyDriverService.uploadDriver(fyUpDataShippingNoteDTO.getDriverId(), domainURL);
//        }
//
//        if(!"1".equals( fyUpDataShippingNoteDTO.getVehicleUploadStatus() )){
//            hyFyVehicleService.uploadVehicle(fyUpDataShippingNoteDTO.getVehicleId(), domainURL);
//        }

        Result rDriver = this.hyFyDriverService.uploadDriver(fyUpDataShippingNoteDTO.getDriverId(), domainURL);
        if (!rDriver.getCode().equals(CommonConstant.SC_OK_200)) {
            throw new JeecgBootException(rDriver.getMessage());
        }

        Result rVehicle = this.hyFyVehicleService.uploadVehicle(fyUpDataShippingNoteDTO.getVehicleId(), domainURL);
        if (!rVehicle.getCode().equals(CommonConstant.SC_OK_200)) {
            throw new JeecgBootException(rVehicle.getMessage());
        }

        FyOrderDTO fyOrderDTO = this.shippingNoteTOFyOrderDTO(
                shippingNote,hyCustomer ,hyDriver ,hyVehicle ,hyDriverBank, domainURL);

        HyFyShipping hyFyShipping = this.hyFyShippingService.getByShippingId(shippingNote.getId());
        if (ObjectUtil.isNotEmpty(hyFyShipping) && "1".equals(hyFyShipping.getUploadStatus())) {

            fyOrderDTO.setOrderNumber(hyFyShipping.getFanyunWaybillNumber());
            if (!"1".equals(hyFyShipping.getIzConfirm())) {
                this.signOff0rder2(hyFyShipping);
            }
            if (StringUtils.isBlank(hyFyShipping.getWriteoffBillNumber())) {
                if(!"1".equals(hyFyShipping.getContract())) {
                    this.cuoheContractPush(hyFyShipping, hyDriver, shippingNote, domainURL);
                }
                //司机费用结算
//                if (hyShippingNoteBills.size() == 1) {
//                    this.upSettlement( hyDriver , hyFyShipping);
//                    this.writeoffPush( shippingNote ,
//                                hyShippingNoteBills ,
//                                hyDriver ,
//                                hyDriverBank,
//                                hyVehicle.getVehicleNumber());
//                } else { //多次支付
                    //分笔核销司机费用
                    this.upSettlementMatchUp(hyDriver, hyFyShipping);
                    this.settlementPushMatchUp(shippingNote, hyShippingNoteBills);
//                }
            }

            return this.updateOrder(fyOrderDTO);
        } else {

            //没有梵运运单状态信息，需要创建一个
            if (ObjectUtil.isEmpty(hyFyShipping)) {
                hyFyShipping = new HyFyShipping();
                hyFyShipping.setShippingId(shippingNote.getId());
                hyFyShipping.setShippingNoteNumber(shippingNote.getShippingNoteNumber());
                hyFyShipping.setUploadTime(new Date());
            }

            Result rCreateRes = this.createOrder(fyOrderDTO, shippingNote.getShippingNoteNumber());
            if (rCreateRes.getCode().equals(CommonConstant.SC_OK_200)) {
                //更新运单上报状态
                if (ObjectUtil.isNotEmpty(rCreateRes.getResult())) {
                    //梵运撮合开单回执 <- {"code":200,"message":null,"data":["S2308170955165538"]}
                    hyFyShipping.setFanyunWaybillNumber(rCreateRes.getResult().toString());
                }
                hyFyShipping.setUploadStatus("1");
                this.saveOrUpdateFyShipping(hyFyShipping);

                //合同
                if(!"1".equals(hyFyShipping.getContract())){
                    this.contractPush(hyDriver, shippingNote, domainURL, hyFyShipping);
                }

                //轨迹
                this.gpsPush(hyVehicle, shippingNote, hyFyShipping.getFanyunWaybillNumber());

                if(!"1".equals(hyFyShipping.getIzConfirm())) {
                    this.signOff0rder2(hyFyShipping);
                }
                if(StringUtils.isBlank(hyFyShipping.getWriteoffBillNumber())) {
                    //司机费用结算
//                    if(hyShippingNoteBills.size() == 1 ){
//                        this.upSettlement( hyDriver , hyFyShipping);
//                        this.writeoffPush( shippingNote ,
//                                hyShippingNoteBills ,
//                                hyDriver ,
//                                hyDriverBank,
//                                hyVehicle.getVehicleNumber()  );
//                    }else{ //多次支付
                        //分笔核销司机费用
                        this.upSettlementMatchUp(hyDriver, hyFyShipping);
                        this.settlementPushMatchUp(shippingNote, hyShippingNoteBills);
//                    }
                }
            } else {
                hyFyShipping.setUploadStatus("2");
                hyFyShipping.setUploadFailureReason(rCreateRes.getMessage());
                this.saveOrUpdateFyShipping(hyFyShipping);
            }

           return rCreateRes;
        }
    }

    @Override
    public HyFyShipping getByShippingId(String shippingId) {
       return this.getOne(new LambdaQueryWrapper<HyFyShipping>().eq(HyFyShipping::getShippingId, shippingId));
    }

    /**
     * 组装数据
     * @param shippingNote
     * @param hyCustomer
     * @param hyDriver
     * @param hyVehicle
     * @param hyDriverBank
     * @param domianURL
     * @return
     */
    private FyOrderDTO shippingNoteTOFyOrderDTO(HyShippingNote shippingNote,
                                                HyCustomer hyCustomer,
                                                HyDriver hyDriver,
                                                HyVehicle hyVehicle,
                                                HyDriverBank hyDriverBank,
                                                String domianURL){
        FyOrderDTO fyOrderDTO = new FyOrderDTO();

        fyOrderDTO.setOriginalOrderNumber(shippingNote.getShippingNoteNumber()) ;

        fyOrderDTO.setOpenTime( shippingNote.getStatusDtReceive().getTime()/1000);
        fyOrderDTO.setDeliveryTime(shippingNote.getStatusDtLoading().getTime()/1000);
        fyOrderDTO.setAppointArriveTime(shippingNote.getStatusDtUnloading().getTime()/1000);

        fyOrderDTO.setStartAddress(shippingNote.getSendAddress());
        fyOrderDTO.setEndAddress(shippingNote.getReceiveAddress());

        fyOrderDTO.setConsignerName(hyCustomer.getCustomerName());
        fyOrderDTO.setConsignerPhone(hyCustomer.getLoginPhone());
        fyOrderDTO.setConsignerIdCard(StrUtil.isNotEmpty(hyCustomer.getCreditCode()) ? hyCustomer.getCreditCode() : hyCustomer.getIdcard());
        fyOrderDTO.setConsignerAddress(
                new FyAddressDTO()
                        .setAddress(shippingNote.getSendAddress())
                        .setDistrictCode(shippingNote.getSendAreaCode())
                        .setLng(shippingNote.getSendLongitude())
                        .setLat(shippingNote.getSendLatitude())
        ) ;

        //fyOrderDTO.setConsigneeName(shippingNote.getReceiveContactName()+"先生");
        fyOrderDTO.setConsigneeName(shippingNote.getReceiveContactName());
        fyOrderDTO.setConsigneePhone(shippingNote.getReceiveContactTel());
//        fyOrderDTO.setConsigneeIdCard(shippingNote.getReceiveContactTel()) ;
        fyOrderDTO.setConsigneeAddress(
                new FyAddressDTO()
                        .setAddress(shippingNote.getReceiveAddress())
                        .setDistrictCode(shippingNote.getReceiveAreaCode())
                        .setLng(shippingNote.getReceiveLongitude())
                        .setLat(shippingNote.getReceiveLatitude())
        ) ;

        List<FyCargoListDTO> cargoList = new ArrayList<>();
        cargoList.add(
                new FyCargoListDTO()
                        .setName(shippingNote.getDescriptionOfGoods())
                        .setTypeCode(shippingNote.getCargoTypeClassificationCode())
                        .setValue(shippingNote.getDriverFee())
                        .setWeight(shippingNote.getGoodsWeightLoading())
                        .setUnloadWeight(shippingNote.getGoodsWeightUnloading())
        );
        fyOrderDTO.setCargoList(cargoList);

        fyOrderDTO.setCarrier(
                new FyCarrierDTO()
                        .setCarNumber(hyVehicle.getVehicleNumber())
                        .setDriverName(hyDriver.getDriverName())
                        .setDriverPhone(hyDriver.getTelephone())
                        .setDriverFreight(shippingNote.getDriverFee())
        );

        FyPayeeDTO fyPayeeDTO = new FyPayeeDTO() ;
        fyPayeeDTO.setName(hyDriver.getDriverName());
        fyPayeeDTO.setIdCard(hyDriver.getIdcard());
        fyPayeeDTO.setPhoneNumber(hyDriver.getTelephone());
//        fyPayeeDTO.setBankCardNumber(
//                hyDriverAccountBook.getProv() + hyDriverAccountBook.getAccNo() + hyDriverAccountBook.getLogAccNo()
//        );
        fyPayeeDTO.setBankName(CheckBankCardIUtil.getBankNameByBankCode(hyDriverBank.getBankType()));
        fyPayeeDTO.setBankCardNumber(hyDriverBank.getBankNum());
        fyOrderDTO.setPayee(fyPayeeDTO);

        fyOrderDTO.setFreightIn(
                new FyFreightInDTO()
                        .setAmount(shippingNote.getDriverFee())
        );

        if (StrUtil.isNotEmpty(shippingNote.getImgLoading())) {
            List<String> imgloadingsAll = Arrays.asList(shippingNote.getImgLoading().split(","));
            List<String> imgloadingsTemp = new ArrayList<>();
            for(String imgloading : imgloadingsAll){
                imgloadingsTemp.add(domianURL+imgloading);
            }

            fyOrderDTO.setLoadImages(imgloadingsTemp) ;
        }

        if (StrUtil.isNotEmpty(shippingNote.getImgUnloading())) {
            List<String> imgUnloadingsAll = Arrays.asList(shippingNote.getImgUnloading().split(","));
            List<String> imgUnloadingsTemp = new ArrayList<>();
            for(String imgUnloading : imgUnloadingsAll){
                imgUnloadingsTemp.add(domianURL+imgUnloading);
            }

            fyOrderDTO.setUnloadImages(imgUnloadingsTemp) ;
        }

        return fyOrderDTO;

    }

    /**
     *
     * @param fyOrderDTO
     * @param shippingNoteNumber
     * @return
     */
    private Result createOrder(FyOrderDTO fyOrderDTO ,String shippingNoteNumber){

        String res = fanyunApiService.createOrder(fyOrderDTO);
//        HyFyShipping hyFyShipping = new HyFyShipping();
//        hyFyShipping.setShippingId(shippingId);
//        hyFyShipping.setShippingNoteNumber(shippingNoteNumber);
//        hyFyShipping.setUploadTime(new Date());

        if (StringUtils.isBlank(res)) {
//            hyFyShipping.setUploadStatus("2");
//            hyFyShipping.setUploadFailureReason("推送异常");
//            this.saveOrUpdateFyShipping(hyFyShipping);
//            throw new JeecgBootException("该运单推送异常！");
            return Result.error("该运单数据推送失败");
        } else {
            FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
            if (200 == r.getCode()) {
                String rData =  r.getData().toString();
                JSONArray rDatas = JSONObject.parseArray(rData);
//                hyFyShipping.setUploadStatus("1");
//                hyFyShipping.setFanyunWaybillNumber(rDatas.get(0).toString());
//                this.saveOrUpdateFyShipping(hyFyShipping);
//                return true;
                return Result.OK(rDatas.get(0).toString());
            } else {
                if (r.getMessage().contains("已存在")) {
//                    hyFyShipping.setUploadStatus("1");
//                    this.saveOrUpdateFyShipping(hyFyShipping);
                    return Result.OK();
                } else {
//                    hyFyShipping.setUploadStatus("2");
//                    hyFyShipping.setUploadFailureReason(r.getMessage());
//                    this.saveOrUpdateFyShipping(hyFyShipping);
                    //throw new JeecgBootException("推送失败，运单 " + shippingNoteNumber + r.getMessage());
                    return Result.error("推送失败，运单 " + shippingNoteNumber + r.getMessage());
                }

            }
        }
    }


    /**
     * 更新运单
     * @param fyOrderDTO
     * @return
     */
    private Result updateOrder(FyOrderDTO fyOrderDTO ){
        String res =  fanyunApiService.updateOrder(fyOrderDTO);
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if (200 == r.getCode()) {
            return Result.OK();
        } else {
            throw new JeecgBootException(r.getMessage());
        }
    }
    /**
     * 确认签收运单
     * @param orderNumbers
     * @return
     */
    @Override
    public boolean signOff0rder(List<String> orderNumbers){
        String res =  fanyunApiService.signOff0rder(orderNumbers);
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if ( 200 == r.getCode()) {
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }

    }

    private boolean signOff0rder2(HyFyShipping hyFyShipping ){

        String res =  fanyunApiService.signOff0rder(
                Collections.singletonList(hyFyShipping.getFanyunWaybillNumber())
        );
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if ( 200 == r.getCode()) {
            hyFyShipping.setIzConfirm("1");
            this.updateById(hyFyShipping);
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }

    }
    /**
     * 取消运单
     * @param orderNumbers
     * @return
     */
    @Override
    public  boolean cancelOrder(List<String> orderNumbers){
        String res =  fanyunApiService.cancelOrder(orderNumbers);
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if ( 200 == r.getCode()) {
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }
    }

    /**
     * 创建司机费用结算单
     * @param hyDriver
     * @param hyFyShipping
     * @return
     */
    private boolean upSettlement(HyDriver hyDriver ,HyFyShipping hyFyShipping ){

        FySettlementDTO fySettlementDTO = new FySettlementDTO();
        fySettlementDTO.setName(hyDriver.getDriverName());
        fySettlementDTO.setPhone(hyDriver.getTelephone());
        fySettlementDTO.setCustomerOrderNumbers(
                Collections.singletonList(hyFyShipping.getFanyunWaybillNumber())
        );
        String res =  fanyunApiService.financePush(fySettlementDTO);
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if ( 200 == r.getCode()) {
            hyFyShipping.setWriteoffBillNumber(r.getData().toString()) ;
            this.updateById(hyFyShipping);
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }

    }

    /**
     * 创建司机费用结算单（撮合）
     * @param hyDriver
     * @param hyFyShipping
     * @return
     */
    private boolean upSettlementMatchUp(HyDriver hyDriver ,HyFyShipping hyFyShipping ){

        FySettlementDTO fySettlementDTO = new FySettlementDTO();
        fySettlementDTO.setName(hyDriver.getDriverName());
        fySettlementDTO.setPhone(hyDriver.getTelephone());
        fySettlementDTO.setCustomerOrderNumbers(
                Collections.singletonList(hyFyShipping.getFanyunWaybillNumber())
        );
        String res = this.fanyunApiService.financePushMatchUp(fySettlementDTO);
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if ( 200 == r.getCode()) {
            hyFyShipping.setWriteoffBillNumber(r.getData().toString()) ;
            this.updateById(hyFyShipping);
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }

    }
    /**
     * 全部核销,不支持多笔核销
     * @param shippingNote
     * @param hyShippingNoteBills
     * @param hyDriver
     * @param hyDriverBank
     * @param carNumber
     * @return
     */
    private  boolean writeoffPush(HyShippingNote shippingNote ,
                                  List<HyShippingNoteBill> hyShippingNoteBills ,
                                  HyDriver hyDriver,
                                  HyDriverBank hyDriverBank,
                                  String carNumber
                                  ){
        HyFyShipping fyShippingDb = this.getById(shippingNote.getId());

        HyShippingNoteBill shippingNoteBill = hyShippingNoteBills.get(0);
        String tradeNo =  shippingNoteBill.getBillNum();

        FySettlement fySettlement = new FySettlement();
        fySettlement.setCarNumber(carNumber);
        fySettlement.setDriverName(hyDriver.getDriverName());
        fySettlement.setDriverPhone(hyDriver.getTelephone());

        fySettlement.setCustomerOrderNumbers(
                Collections.singletonList(fyShippingDb.getFanyunWaybillNumber())
        );
        fySettlement.setPayFreight(shippingNote.getDriverFee());
        fySettlement.setTradeNo(tradeNo);

        FyPayeeDTO fyPayeeDTO = new FyPayeeDTO() ;
        fyPayeeDTO.setName(hyDriver.getDriverName());
        fyPayeeDTO.setIdCard(hyDriver.getIdcard());
        fyPayeeDTO.setPhoneNumber(hyDriver.getTelephone());
        fyPayeeDTO.setBankName(CheckBankCardIUtil.getBankNameByBankCode(hyDriverBank.getBankType()));
        fyPayeeDTO.setBankCardNumber(hyDriverBank.getBankNum());
//        fyPayeeDTO.setBankCardNumber(
//                hyDriverAccountBook.getProv() + hyDriverAccountBook.getAccNo() + hyDriverAccountBook.getLogAccNo()
//        );
        fySettlement.setPayee(fyPayeeDTO);

        String res = fanyunApiService.writeoffPush(fySettlement);
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if ( 200 == r.getCode()) {
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }
    }


    /**
     * 分笔核销司机费用结算单
     * @param shippingNote
     * @param hyShippingNoteBills
     * @return
     */
    private  boolean settlementPush( HyShippingNote shippingNote ,  List<HyShippingNoteBill> hyShippingNoteBills ){

        HyFyShipping fyShippingDb = this.getById(shippingNote.getId());
        HyShippingNoteBill shippingNoteBill = hyShippingNoteBills.get(0);
        String tradeNo =  shippingNoteBill.getBillNum();
        FySettlement fySettlement = new FySettlement();
        fySettlement.setSettlementNumber(fyShippingDb.getWriteoffBillNumber());
        fySettlement.setPayFreight(shippingNote.getDriverFee());
        fySettlement.setTradeNo(tradeNo);
        String res =  fanyunApiService.fySettlementPush(fySettlement);
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if ( 200 == r.getCode()) {
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }
    }


    /**
     * 分笔核销司机费用结算单（撮合）
     * @param shippingNote
     * @param hyShippingNoteBills
     * @return
     */
    private  boolean settlementPushMatchUp( HyShippingNote shippingNote ,  List<HyShippingNoteBill> hyShippingNoteBills ){
        HyFyShipping fyShippingDb = this.getById(shippingNote.getId());
        HyShippingNoteBill shippingNoteBill = hyShippingNoteBills.get(0);
        String tradeNo =  shippingNoteBill.getBillNum();
        FySettlement fySettlement = new FySettlement();
        fySettlement.setSettlementNumber(fyShippingDb.getWriteoffBillNumber());
        fySettlement.setPayFreight(shippingNote.getDriverFee());
        fySettlement.setTradeNo(tradeNo);
        String res =  fanyunApiService.fySettlementPushMatchUp(fySettlement);
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if ( 200 == r.getCode()) {
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }
    }


    /**
     * 创建承运人合同
     * @param hyDriver
     * @param shippingNote
     * @param domianURL
     * @param hyFyShipping
     * @return
     */
    private boolean contractPush(HyDriver hyDriver, HyShippingNote shippingNote, String domianURL, HyFyShipping hyFyShipping ){

        CarrierContractDTO carrierContractDTO = new CarrierContractDTO();
        carrierContractDTO.setNumber(shippingNote.getContractNum()) ;
        carrierContractDTO.setName(hyDriver.getDriverName());
        carrierContractDTO.setCertNo(hyDriver.getIdcard());
        carrierContractDTO.setPhone(hyDriver.getTelephone());

        Date createTime = shippingNote.getCreateTime();
        String startDateString = DateUtils.date2Str(createTime,DateUtils.date_sdf.get()) ;

        Calendar calendar = new GregorianCalendar();
        calendar.setTime(createTime);
        calendar.add(Calendar.DATE, 15);// 把日期往后增加一天.整数往后推,负数往前移动
        Date lasDate = calendar.getTime(); // 这个时间就是日期往后推一天的结果
        String endDateString =  DateUtils.date2Str(lasDate, DateUtils.date_sdf.get());

        carrierContractDTO.setContractDate(startDateString);
        carrierContractDTO.setStartDate(startDateString);
        carrierContractDTO.setEndDate(endDateString);
        carrierContractDTO.setFileUrl(
                domianURL + shippingNote.getShippingContract()
        );

        String res = fanyunApiService.contractPush(carrierContractDTO);
        FyApiBaseResDTO r = JSONObject.parseObject(res, FyApiBaseResDTO.class);
        if (200 == r.getCode()) {
            hyFyShipping.setContract("1");
            this.updateById(hyFyShipping);
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }
    }

    /**
     * 创建撮合单票承运人合同
     * @param hyFyShipping
     * @param hyDriver
     * @param shippingNote
     * @param domianURL
     * @return
     */
    private boolean cuoheContractPush(HyFyShipping hyFyShipping  ,HyDriver hyDriver ,HyShippingNote shippingNote ,String domianURL ){
        CuoheContractDTO cuoheContractDTO = new CuoheContractDTO();
        cuoheContractDTO.setOrderNumber(hyFyShipping.getFanyunWaybillNumber());
        cuoheContractDTO.setNumber(shippingNote.getContractNum()) ;
        cuoheContractDTO.setName(hyDriver.getDriverName());
        cuoheContractDTO.setCertNo(hyDriver.getIdcard());
        cuoheContractDTO.setPhone(hyDriver.getTelephone());

        Date createTime = shippingNote.getCreateTime();
        String startDateString = DateUtils.date2Str(createTime,DateUtils.date_sdf.get()) ;
        cuoheContractDTO.setContractDate( startDateString );
        cuoheContractDTO.setFileUrl(
//                "https://www.hebeiyiliuba.com/wlhy168/sys/common/static/wlhy/20230208/watermark_20230208022625_9f0ce9e1fb9f4870acce7d68bd2a78e8.jpg"
                domianURL + shippingNote.getShippingContract()
        ) ;

        String res =  fanyunApiService.cuoheContractPush(cuoheContractDTO);
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if ( 200 == r.getCode()) {
            hyFyShipping.setContract("1");
            this.updateById(hyFyShipping);
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }
    }

    /**
     * 上报运单轨迹
     * @param hyVehicle
     * @param hyShippingNote
     * @param fanyunWaybillNumber
     * @return
     */
    private boolean gpsPush(HyVehicle hyVehicle, HyShippingNote hyShippingNote ,String fanyunWaybillNumber ){

        List<GpsDataDTO> gpsDataDTOS = this.getZjListGps(hyVehicle, hyShippingNote) ;  // new ArrayList<>() ;//

//        gpsDataDTOS.add(new GpsDataDTO()
//                .setLongitude(hyShippingNote.getSendLongitude().doubleValue())
//                .setLatitude(hyShippingNote.getSendLatitude().doubleValue())
//                .setLocateTime(hyShippingNote.getStatusDtLoading().getTime()/1000)
//        );

        if (CollectionUtils.isEmpty(gpsDataDTOS)) {
            throw new JeecgBootException("该运单轨迹信息不能为空");
        }

        FyGpsDTO fyGpsDTO = new FyGpsDTO();
        fyGpsDTO.setOrderNumber(fanyunWaybillNumber);
        String res = null;
        if(gpsDataDTOS.size() <= 500){
             fyGpsDTO.setGpsDataList(gpsDataDTOS);
             res =  fanyunApiService.gpsPush(fyGpsDTO);
        }else{
            //位置信息列表，如果定位点较多，超过了单次请求的数量限制，则多次调用
            int section = 500;
            for (int index = 0, end = 0; index < gpsDataDTOS.size(); index = end) {
                end = (end + section) <= gpsDataDTOS.size() ? end + section : gpsDataDTOS.size();
                if (index < end) {
                    fyGpsDTO.setGpsDataList( gpsDataDTOS.subList(index, end) );
                    res =  fanyunApiService.gpsPush(fyGpsDTO);
                }
            }
        }
        FyApiBaseResDTO r = JSONObject.parseObject(res , FyApiBaseResDTO.class);
        if ( 200 == r.getCode()) {
            return true;
        }else{
            throw new JeecgBootException(r.getMessage());
        }
    }

    public static void main(String[] args) {
      int  count = 1023;
      int size = 500;
      int a  =   (int) (count%size==0?count/size:count/size+1);
        System.out.println(a);

    }



    /**
     * 上报获取运单轨迹gps数据
     *
     * @param hyVehicle
     * @param hyShippingNote
     * @return
     */
    private List<GpsDataDTO> getZjListGps(HyVehicle hyVehicle, HyShippingNote hyShippingNote) {
        List<GpsDataDTO> gpsDTOS = new ArrayList<>();

        try {
            String startTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtReceive());
            String endTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtUnloading());
            String vehicleColor = StringUtils.isNotEmpty(hyVehicle.getVehiclePlateColorCode()) ? hyVehicle.getVehiclePlateColorCode() : "2";
            WaybillRouteVO waybillRouteVO = waybillRouteService.getWaybillRoute(hyVehicle.getVehicleNumber(), vehicleColor, startTime, endTime, "GCJ02");
            if (waybillRouteVO != null && CollectionUtils.isNotEmpty(waybillRouteVO.getPointDataList())) {
                List<PointDataListVO> pointDataListVOS = waybillRouteVO.getPointDataList();
                Integer a = pointDataListVOS.size();

                if (a <= 500) {
                    for (PointDataListVO pointDataListVO : pointDataListVOS) {
                        GpsDataDTO gpsDTO = new GpsDataDTO();
                        gpsDTO.setLongitude(Double.valueOf(pointDataListVO.getLng()));
                        gpsDTO.setLatitude(Double.valueOf(pointDataListVO.getLat()));
                        gpsDTO.setLocateTime(
                                DateUtils.stringToDateTime (pointDataListVO.getReceiveTime()).getTime()/1000
                        );
                        gpsDTOS.add(gpsDTO);
                    }
                } else {
                    Integer b = this.getFrequency(a);
                    Integer n = 1;
                    for (PointDataListVO pointDataListVO : pointDataListVOS) {
                        if (n % b == 0) {
                            GpsDataDTO gpsDTO = new GpsDataDTO();
                            gpsDTO.setLongitude(Double.valueOf(pointDataListVO.getLng()));
                            gpsDTO.setLatitude(Double.valueOf(pointDataListVO.getLat()));
                            gpsDTO.setLocateTime(
                                    DateUtils.stringToDateTime (pointDataListVO.getReceiveTime()).getTime()/1000
                            );
                            gpsDTOS.add(gpsDTO);
                        }
                        n++;
                    }
                }

            }
            return gpsDTOS;
        }catch (Exception e){
            LOGGER.info("HyFyShippingServiceImpl  getZjListGps  Exception |{}", e.getMessage());
        }
        return gpsDTOS;
    }

    /**
     * 获取频次
     *
     * @param a
     * @return
     */
    private Integer getFrequency(Integer a) {
        Integer b = 1;
        if (a > 500 && a <= 2000) {
            b = 10;
        } else if (a > 2000 && a <= 3000) {
            b = 20;
        } else if (a > 3000 && a <= 4000) {
            b = 30;
        } else if (a > 4000 && a <= 5000) {
            b = 40;
        } else if (a > 5000 && a <= 6000) {
            b = 50;
        } else {
            b = 60;
        }
        return b;
    }

    @Override
    public boolean saveOrUpdateFyShipping(HyFyShipping hyFyShipping){
        try {
            hyFyShipping.setId(hyFyShipping.getShippingId());
            return this.saveOrUpdate(hyFyShipping);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return false;
    }
}
